package com.gpj.learn.rabbitmq.helloworld;

import com.gpj.learn.rabbitmq.common.CommonConstants;
import com.rabbitmq.client.*;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @className Consumer
 * @description
 *   TODO
 * @author GPJ
 * @date 2021/5/30 12:09
 * @version 1.0
 **/
@Slf4j
public class Consumer {
	public static void main(String[] args) throws IOException, TimeoutException {
		log.info("------------- 开始消费消息 -------------");
		// 获取TCP长连接
		ConnectionFactory factory = new ConnectionFactory();
		factory.setHost(CommonConstants.RABBITMQ_HOST);
		factory.setPort(CommonConstants.RABBITMQ_PORT);
		factory.setUsername(CommonConstants.RABBITMQ_USER);
		factory.setPassword(CommonConstants.RABBITMQ_PASSWORD);
		factory.setVirtualHost(CommonConstants.RABBITMQ_VIRTUALHOST);

		Connection connection = factory.newConnection();

		// 获取通道
		Channel channel = connection.createChannel();

		// 创建队列
		channel.queueDeclare(
				CommonConstants.RABBITMQ_QUEUE_HELLOWORLD, // 队列名称
				false, // 是否持久化,false-不持久化
				false, // 是否队列私有化,false-非私有化,全部消费者均可消费;true-私有化,第一次拥有该队列的消费者才可以使用
				false, // 是否自动删除,false-连接停止之后不自动删除该队列
				null); // 额外参数

		// 消费消息
		//创建一个消息消费者
		//第一个参数：队列名
		//第二个参数代表是否自动确认收到消息，false代表手动编程来确认消息，这是MQ的推荐做法
		//第三个参数要传入DefaultConsumer的实现类
		channel.basicConsume(
				CommonConstants.RABBITMQ_QUEUE_HELLOWORLD, // 队列名
				false, // 是否自动确认接收消息,false-手动确定(MQ推荐);true-自动确认
				new DefaultConsumer(channel){ // 消息消费类
					@Override
					public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
						String message = new String(body);
						log.info("接收到消息[{}]:{}", envelope.getDeliveryTag(), message);
						//false只确认签收当前的消息，设置为true的时候则代表签收该消费者所有未签收的消息
						channel.basicAck(envelope.getDeliveryTag(), false);
					}
				});
	}
}
